<template>
	<view class="container">
		<view class="header">
			<text class="title">H5录音插件测试</text>
			<text class="subtitle">兼容uni.getRecorderManager API</text>
		</view>
		
		<view class="status-panel">
			<view class="status-item">
				<text class="label">录音状态：</text>
				<text class="value" :class="statusClass">{{ recordStatus }}</text>
			</view>
			<view class="status-item" v-if="recordDuration > 0">
				<text class="label">录音时长：</text>
				<text class="value">{{ recordDuration }}秒</text>
			</view>
			<view class="status-item" v-if="recordFileSize > 0">
				<text class="label">文件大小：</text>
				<text class="value">{{ formatFileSize(recordFileSize) }}</text>
			</view>
		</view>
		
		<view class="control-panel">
			<button 
				class="control-btn start-btn" 
				@tap="startRecord"
				:disabled="isRecording">
				开始录音
			</button>
			
			<button 
				class="control-btn pause-btn" 
				@tap="pauseRecord"
				:disabled="!isRecording || isPaused">
				暂停录音
			</button>
			
			<button 
				class="control-btn resume-btn" 
				@tap="resumeRecord"
				:disabled="!isPaused">
				继续录音
			</button>
			
			<button 
				class="control-btn stop-btn" 
				@tap="stopRecord"
				:disabled="!isRecording">
				停止录音
			</button>
			
			<button 
				class="control-btn play-btn" 
				@tap="playRecord"
				:disabled="!recordFile || isPlaying">
				播放录音
			</button>
		</view>
		
		<view class="config-panel">
			<text class="panel-title">录音配置</text>
			
			<view class="config-item">
				<text class="config-label">录音格式：</text>
				<picker @change="onFormatChange" :value="formatIndex" :range="formatOptions">
					<view class="picker-value">{{ formatOptions[formatIndex] }}</view>
				</picker>
			</view>
			
			<view class="config-item">
				<text class="config-label">采样率：</text>
				<picker @change="onSampleRateChange" :value="sampleRateIndex" :range="sampleRateOptions">
					<view class="picker-value">{{ sampleRateOptions[sampleRateIndex] }}</view>
				</picker>
			</view>
			
			<view class="config-item">
				<text class="config-label">录音时长：</text>
				<picker @change="onDurationChange" :value="durationIndex" :range="durationLabels">
					<view class="picker-value">{{ durationLabels[durationIndex] }}</view>
				</picker>
			</view>
		</view>
		
		<view class="log-panel">
			<text class="panel-title">日志信息</text>
			<scroll-view class="log-content" scroll-y>
				<view class="log-item" v-for="(log, index) in logs" :key="index">
					<text class="log-time">{{ log.time }}</text>
					<text class="log-message">{{ log.message }}</text>
				</view>
			</scroll-view>
		</view>
	</view>
</template>

<script>
import jzRecorder from '@/uni_modules/jz-h5RecorderManager/js/index.js'

export default {
	data() {
		return {
			recorderManager: null,
			audioContext: null,
			recordFile: null,
			recordDuration: 0,
			recordFileSize: 0,
			isRecording: false,
			isPaused: false,
			isPlaying: false,
			
			// 录音配置
			formatIndex: 0,
			formatOptions: ['mp3', 'wav', 'aac', 'PCM'],
			sampleRateIndex: 2,
			sampleRateOptions: ['8000', '16000', '44100'],
			durationIndex: 1,
			durationLabels: ['30秒', '60秒', '120秒', '300秒'],
			durationValues: [30000, 60000, 120000, 300000],
			
			// 日志
			logs: []
		}
	},
	
	computed: {
		recordStatus() {
			if (this.isRecording) {
				return this.isPaused ? '已暂停' : '录音中'
			}
			return '未开始'
		},
		
		statusClass() {
			if (this.isRecording) {
				return this.isPaused ? 'status-paused' : 'status-recording'
			}
			return 'status-idle'
		}
	},
	
	onLoad() {
		this.initRecorder()
		this.addLog('页面加载完成')
	},
	
	onUnload() {
		this.cleanup()
	},
	
	methods: {
		// 初始化录音器
		initRecorder() {
			try {
				// 获取录音管理器
				this.recorderManager = jzRecorder.getRecorderManager()
				
				// 获取音频播放器
				this.audioContext = uni.createInnerAudioContext()
				this.audioContext.autoplay = true
				
				// 监听录音事件
				this.setupRecorderEvents()
				
				// 监听播放事件
				this.setupAudioEvents()
				
				this.addLog('录音管理器初始化成功')
			} catch (error) {
				this.addLog('录音管理器初始化失败: ' + error.message)
			}
		},
		
		// 设置录音事件监听
		setupRecorderEvents() {
			// 录音开始
			this.recorderManager.onStart(() => {
				this.isRecording = true
				this.isPaused = false
				this.addLog('录音开始')
				uni.showToast({ title: '录音开始', icon: 'none' })
			})
			
			// 录音暂停
			this.recorderManager.onPause(() => {
				this.isPaused = true
				this.addLog('录音暂停')
				uni.showToast({ title: '录音暂停', icon: 'none' })
			})
			
			// 录音继续
			this.recorderManager.onResume(() => {
				this.isPaused = false
				this.addLog('录音继续')
				uni.showToast({ title: '录音继续', icon: 'none' })
			})
			
			// 录音停止
			this.recorderManager.onStop((res) => {
				this.isRecording = false
				this.isPaused = false
				this.recordFile = res.tempFilePath
				this.recordDuration = Math.round(res.duration || 0)
				this.recordFileSize = res.fileSize || 0
				
				this.addLog(`录音停止，时长：${this.recordDuration}秒，大小：${this.formatFileSize(this.recordFileSize)}`)
				uni.showToast({ 
					title: `录音完成，时长：${this.recordDuration}秒`, 
					icon: 'success' 
				})
			})
			
			// 录音错误
			this.recorderManager.onError((err) => {
				this.isRecording = false
				this.isPaused = false
				this.addLog('录音错误: ' + err.errMsg)
				uni.showToast({ title: err.errMsg, icon: 'none' })
			})
			
			// 帧录制回调
			this.recorderManager.onFrameRecorded((res) => {
				this.addLog(`录制帧数据，大小：${res.frameBuffer.byteLength}字节`)
			})
		},
		
		// 设置音频播放事件监听
		setupAudioEvents() {
			this.audioContext.onPlay(() => {
				this.isPlaying = true
				this.addLog('开始播放录音')
			})
			
			this.audioContext.onEnded(() => {
				this.isPlaying = false
				this.addLog('录音播放完成')
			})
			
			this.audioContext.onError((err) => {
				this.isPlaying = false
				this.addLog('播放错误: ' + (err.errMsg || '播放失败'))
			})
		},
		
		// 开始录音
		startRecord() {
			const config = {
				duration: this.durationValues[this.durationIndex],
				sampleRate: parseInt(this.sampleRateOptions[this.sampleRateIndex]),
				numberOfChannels: 1,
				encodeBitRate: 192000,
				format: this.formatOptions[this.formatIndex]
			}
			
			this.addLog(`开始录音，配置：${JSON.stringify(config)}`)
			this.recorderManager.start(config)
		},
		
		// 暂停录音
		pauseRecord() {
			this.recorderManager.pause()
		},
		
		// 继续录音
		resumeRecord() {
			this.recorderManager.resume()
		},
		
		// 停止录音
		stopRecord() {
			this.recorderManager.stop()
		},
		
		// 播放录音
		playRecord() {
			if (this.recordFile) {
				this.audioContext.src = this.recordFile
				this.audioContext.play()
			} else {
				uni.showToast({ title: '请先录音', icon: 'none' })
			}
		},
		
		// 格式选择
		onFormatChange(e) {
			this.formatIndex = e.detail.value
			this.addLog(`切换录音格式为：${this.formatOptions[this.formatIndex]}`)
		},
		
		// 采样率选择
		onSampleRateChange(e) {
			this.sampleRateIndex = e.detail.value
			this.addLog(`切换采样率为：${this.sampleRateOptions[this.sampleRateIndex]}`)
		},
		
		// 录音时长选择
		onDurationChange(e) {
			this.durationIndex = e.detail.value
			this.addLog(`切换录音时长为：${this.durationLabels[this.durationIndex]}`)
		},
		
		// 格式化文件大小
		formatFileSize(bytes) {
			if (bytes === 0) return '0 B'
			const k = 1024
			const sizes = ['B', 'KB', 'MB', 'GB']
			const i = Math.floor(Math.log(bytes) / Math.log(k))
			return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
		},
		
		// 添加日志
		addLog(message) {
			const now = new Date()
			const time = now.toLocaleTimeString()
			this.logs.unshift({
				time: time,
				message: message
			})
			
			// 限制日志数量
			if (this.logs.length > 50) {
				this.logs = this.logs.slice(0, 50)
			}
		},
		
		// 清理资源
		cleanup() {
			if (this.audioContext) {
				this.audioContext.destroy()
			}
			
			if (this.recordFile && this.recordFile.startsWith('blob:')) {
				URL.revokeObjectURL(this.recordFile)
			}
		}
	}
}
</script>

<style scoped>
.container {
	padding: 20rpx;
	min-height: 100vh;
	background-color: #f5f5f5;
}

.header {
	text-align: center;
	margin-bottom: 30rpx;
}

.title {
	font-size: 36rpx;
	font-weight: bold;
	color: #333;
	display: block;
	margin-bottom: 10rpx;
}

.subtitle {
	font-size: 28rpx;
	color: #666;
	display: block;
}

.status-panel {
	background: white;
	border-radius: 16rpx;
	padding: 30rpx;
	margin-bottom: 30rpx;
	box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}

.status-item {
	display: flex;
	align-items: center;
	margin-bottom: 20rpx;
}

.status-item:last-child {
	margin-bottom: 0;
}

.label {
	font-size: 28rpx;
	color: #666;
	min-width: 160rpx;
}

.value {
	font-size: 28rpx;
	font-weight: bold;
}

.status-idle {
	color: #999;
}

.status-recording {
	color: #ff4757;
}

.status-paused {
	color: #ffa502;
}

.control-panel {
	background: white;
	border-radius: 16rpx;
	padding: 30rpx;
	margin-bottom: 30rpx;
	box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}

.control-btn {
	width: 100%;
	height: 80rpx;
	border-radius: 40rpx;
	font-size: 28rpx;
	font-weight: bold;
	margin-bottom: 20rpx;
	color: white;
	border: none;
}

.control-btn:last-child {
	margin-bottom: 0;
}

.start-btn {
	background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

.pause-btn {
	background: linear-gradient(135deg, #ffa502 0%, #ff6348 100%);
}

.resume-btn {
	background: linear-gradient(135deg, #2ed573 0%, #7bed9f 100%);
}

.stop-btn {
	background: linear-gradient(135deg, #ff4757 0%, #ff3742 100%);
}

.play-btn {
	background: linear-gradient(135deg, #5352ed 0%, #3742fa 100%);
}

.control-btn[disabled] {
	background: #ddd !important;
	color: #999 !important;
}

.config-panel {
	background: white;
	border-radius: 16rpx;
	padding: 30rpx;
	margin-bottom: 30rpx;
	box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}

.panel-title {
	font-size: 32rpx;
	font-weight: bold;
	color: #333;
	margin-bottom: 30rpx;
	display: block;
}

.config-item {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 30rpx;
	padding-bottom: 20rpx;
	border-bottom: 1rpx solid #eee;
}

.config-item:last-child {
	margin-bottom: 0;
	border-bottom: none;
	padding-bottom: 0;
}

.config-label {
	font-size: 28rpx;
	color: #333;
}

.picker-value {
	font-size: 28rpx;
	color: #007aff;
	padding: 10rpx 20rpx;
	background: #f0f9ff;
	border-radius: 8rpx;
}

.log-panel {
	background: white;
	border-radius: 16rpx;
	padding: 30rpx;
	box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}

.log-content {
	height: 400rpx;
	background: #f8f9fa;
	border-radius: 8rpx;
	padding: 20rpx;
}

.log-item {
	margin-bottom: 20rpx;
	padding-bottom: 15rpx;
	border-bottom: 1rpx solid #eee;
}

.log-item:last-child {
	margin-bottom: 0;
	border-bottom: none;
	padding-bottom: 0;
}

.log-time {
	font-size: 24rpx;
	color: #999;
	margin-right: 20rpx;
}

.log-message {
	font-size: 26rpx;
	color: #333;
}
</style>
